package com.tl.commonlibrary.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;

import com.tl.commonlibrary.R;
import com.tl.commonlibrary.tool.NumberUnit;

import java.math.BigDecimal;

/**
 * Created by Administrator on 2017/6/16 0016.
 */

public class NumberEditText extends android.support.v7.widget.AppCompatEditText implements TextWatcher {
    private int decimalDigits = 2;//保留的小数位
    private double maxValueInt = 0;
    private String maxValue = "0";
    private double minValueInt = 0;
    private String minValue = "0";
    private TextChangedListener listener;
    private OnTextExceedListener exceedListener;

    public NumberEditText(Context context) {
        super(context);
        init(context, null, 0);
    }

    public NumberEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public NumberEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        if (attrs != null) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.NumberEditText);
            decimalDigits = array.getInt(R.styleable.NumberEditText_numDecimalDigits, decimalDigits);
            String temp = array.getString(R.styleable.NumberEditText_maxNumValue);
            if (!TextUtils.isEmpty(temp)) {
                maxValue = temp;
            } else {
                maxValue = "2147483647";
            }
            temp = array.getString(R.styleable.NumberEditText_minNumValue);
            if (!TextUtils.isEmpty(temp)) {
                minValue = temp;
            } else {
                minValue = "0";
            }
        }
        setDecimalDigits(decimalDigits);
        setMaxValue(maxValue);
        setMinValue(minValue);
        addTextChangedListener(this);
    }

    public int getDecimalDigits() {
        return decimalDigits;
    }

    public void setDecimalDigits(int decimalDigits) {
        this.decimalDigits = decimalDigits;
        if (decimalDigits <= 0) {
            setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL);
        } else {
            setInputType(EditorInfo.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
        }
    }

    public String getMaxValue() {
        return maxValue;
    }

    /**
     * 禁止非数值或者超出上限下限
     *
     * @param maxValue
     */
    public void setMaxValue(@NonNull String maxValue) {
        BigDecimal decimal = new BigDecimal(maxValue);
        NumberUnit unit = new NumberUnit(decimal);
        unit.setFormatDot(false);
        this.maxValueInt = decimal.doubleValue();
        this.maxValue = unit.getNF(NumberUnit.KEEP_DECIMAL_DYNAMIC);
    }

    public String getMinValue() {
        return minValue;
    }

    public void setMinValue(@NonNull String minValue) {
        BigDecimal decimal = new BigDecimal(minValue);
        NumberUnit unit = new NumberUnit(decimal);
        unit.setFormatDot(false);
        this.minValueInt = decimal.doubleValue();
        this.minValue = unit.getNF(NumberUnit.KEEP_DECIMAL_DYNAMIC);
    }

    public TextChangedListener getListener() {
        return listener;
    }

    public void addNumberTextChangedListener(TextChangedListener listener) {
        this.listener = listener;
    }

    public OnTextExceedListener getExceedListener() {
        return exceedListener;
    }

    public void setExceedListener(OnTextExceedListener exceedListener) {
        this.exceedListener = exceedListener;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (listener != null) {
            listener.beforeTextChanged(this, s, start, count, after);
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (listener != null) {
            listener.onTextChanged(this, s, start, before, count);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        String temp = s.toString();
        int posZero = temp.indexOf("0");
        int posDot = temp.indexOf(".");
        //清除无效的零（1.至少有两个字符，第一个零后面不紧跟小数点，或者没有小数点）
        if (posZero == 0 && temp.length() >= 2 && posDot != 1) {
            s.delete(0, 1);
        }
        //管理小数点
        if (posDot > 0) {
            if (temp.length() - posDot - 1 > decimalDigits) {
                s.delete(posDot + decimalDigits + 1, posDot + decimalDigits + 2);
                if (exceedListener != null) {
                    exceedListener.onExceedDecimalDigitsValue(this, s, decimalDigits);
                }
            }
        } else if (posDot == 0) {
            s.insert(0, "0");
        }
        //管理最大最小值
        try {
            double tempDouble = Double.parseDouble(s.toString());
            if (tempDouble < minValueInt) {
                s.replace(0,s.length(),minValue);
                if (exceedListener != null) {
                    exceedListener.onExceedMinValue(this, s, minValueInt);
                }
            } else if (maxValueInt != Double.MAX_VALUE) {
                if (tempDouble > maxValueInt) {
                    s.replace(0,s.length(),maxValue);
                    if (exceedListener != null) {
                        exceedListener.onExceedMaxValue(this, s, maxValueInt);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (listener != null) {
                listener.afterTextChanged(this, s);
            }
        }
    }

    public interface TextChangedListener {
        void beforeTextChanged(EditText editText, CharSequence s, int start,
                               int count, int after);

        void onTextChanged(EditText editText, CharSequence s, int start, int before, int count);

        void afterTextChanged(EditText editText, Editable s);
    }

    public interface OnTextExceedListener {
        //超出小数位
        void onExceedDecimalDigitsValue(EditText editText, Editable s, int decimalDigits);

        //超出最大值
        void onExceedMaxValue(EditText editText, Editable s, double maxValue);

        //超出最小值
        void onExceedMinValue(EditText editText, Editable s, double minValue);
    }
}
